#pragma once

#include <memory>
#include <sstream>

#define NEW_OBJECT(class_name, ...) new class_name(__VA_ARGS__)
#define DELETE_OBJECT(obj)\
    if (nullptr != obj)\
    {\
        delete obj;\
    }

template<typename T, typename D>
using UPType = std::unique_ptr<T, D>;

class UniquePtrDeleteClass
{
public:
    UniquePtrDeleteClass() = default;
    template <typename T>
    void operator ()(T* ptr) {
        DELETE_OBJECT(ptr);
    }
};

template<typename T, typename... TArgs>
static UPType<T, UniquePtrDeleteClass> create_unique(TArgs&&... params)
{
    return UPType<T, UniquePtrDeleteClass>(NEW_OBJECT(T, std::forward<TArgs>(params)...), UniquePtrDeleteClass());
}

/// 打印map
template <class T>
static std::string DumpMap(const T &data)
{
    std::stringstream ss;
    ss << "(";
    for (auto &it : data)
    {
        ss << "(" << it.first << "," << it.second << ")";
    }
    ss << ")";
    return ss.str();
}

/// 打印vector
template <class T>
static std::string DumpVector(const T &data)
{
    std::stringstream ss;
    ss << "(";
    for (std::size_t i = 0; i < data.size(); ++i)
    {
        if (i > 0)
        {
            ss << ",";
        }
        ss << data[i];
    }
    ss << ")";
    return ss.str();
}